package com.hc.springcache.service.impl;

import com.hc.springcache.service.RedisCacheService;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;

/**
 * @Author: huangcheng
 * @CreateTime: 2023-09-14  11:40
 * @Description:
 * @Version: 1.0
 */
@Service
@CacheConfig(cacheNames = "CacheConfigName")
public class RedisCacheServiceImpl implements RedisCacheService {

    /**
     * --@Cacheable注解会先查询是否已经有缓存，有会使用缓存，没有则会执行方法并缓存
     * 命名空间:@Cacheable的value会替换@CacheConfig的cacheNames(两者必须有一个)
     * --key是[命名空间]::[@Cacheable的key或者KeyGenerator生成的key]
     * (@Cacheable的key优先级高,KeyGenerator不配置走默认KeyGenerator SimpleKey [])
     */
    @Override
    @Cacheable(value = "myCache",key = "'keyName'")
    public String cacheableTest() {
        System.out.println("查询了数据库");
        return "查询数据库返回结果";
    }
    /**
     * --@CachePut注解的作用 主要针对方法配置，能够根据方法的请求参数对其结果进行缓存，
     * 和 @Cacheable 不同的是，它每次都会触发真实方法的调用
     * 简单来说就是用户更新缓存数据。但需要注意的是该注解的value 和 key 必须与要更新的缓存相同，也就是与@Cacheable 相同
     * 默认先执行数据库更新再执行缓存更新，双写策略
     * 注意返回值必须是要修改后的数据
     */
    @Override
    @CachePut(value = "myCache",key = "'keyName'")
    public String cacheputTest() {
        System.out.println("更新缓存");
        return "更新缓存的结果";
    }

    /**
     * --@CachEvict 的作用 主要针对方法配置，能够根据一定的条件对缓存进行清空
     * 触发缓存清除
     * 默认先执行数据库删除再执行缓存删除
     * allEntries是方法调用后清理，beforeInvocation是方法调用前清理。
     */
    @Override
    @CacheEvict(value = "myCache",allEntries=true)
    public String cacheEvictTest() {
        System.out.println("删除缓存");
        return "缓存删除";
    }

    @Override
    @Caching(
            cacheable = {
                    @Cacheable(value = "myCache", key = "#id")
            },
            evict = {
                    @CacheEvict(value = "otherCache", key = "#id")
            }
    )
    public String cacheTest(String str) {
        return str;
    }
}
